package com.jsj.subway.ai.utils;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.jsj.subway.ai.demo.dto.AlarmMessage;
import com.jsj.subway.ai.demo.dto.ChatDTO;
import com.jsj.subway.ai.largemodel.models.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class LocalCache {

      //全局变量
//      private InheritableThreadLocal<Integer> sharedCounter =
//              new InheritableThreadLocal<Integer>() {
//                    @Override
//                    protected Integer initialValue() {
//                          return 0;
//                    }
//              };

      public void setCounter(Integer counter) {
            sharedCounter.put("counter",counter);
      }

      public Integer getCounter() {
            return sharedCounter.get("counter");
      }

      public void  setSharedMap(AlarmMessage message){
            sharedMap.put("map",message);
      }

      public AlarmMessage getSharedMap(){
            return sharedMap.get("map");
      }

      private LoadingCache<String,Integer> sharedCounter = Caffeine.newBuilder()
              .initialCapacity(16)
              .expireAfterAccess(30,TimeUnit.MINUTES)
              .build(id->{return 0 ;});

      private LoadingCache<String, AlarmMessage> sharedMap = Caffeine.newBuilder()
              .initialCapacity(16)
              .expireAfterAccess(30,TimeUnit.MINUTES)
              .build(id->{return AlarmMessage.builder().build();});


      private LoadingCache<String, SseEmitterUTF8> emitterCache = Caffeine.newBuilder()
              .initialCapacity(1024)
              .expireAfterAccess(30, TimeUnit.MINUTES)
              .build(sseId->{
            return new SseEmitterUTF8(10*60*1000l);
      });


      private  LoadingCache<String, ChatDTO.MessageRecord> tmpMessageCache =
              Caffeine.newBuilder().initialCapacity(1024)
                      // 手动设置10分钟缓存过期，
                      .expireAfterAccess(10l, TimeUnit.MINUTES)
                      //缓存填充策略：同步加载。
                      .build(recordId -> {return null;});

      private LoadingCache<Long, Deque<ChatDTO.MessageRecord>> sessionMessageCache =
              Caffeine.newBuilder()
                      .initialCapacity(1024)
                      .expireAfterAccess(5, TimeUnit.MINUTES)
                      .build(sessionId -> new LinkedList<>());

      // 存储消息记录到缓存中
      public void addMessageRecordToCache(Long sessionId, ChatDTO.MessageRecord messageRecord) {
            Deque<ChatDTO.MessageRecord> messageRecords = sessionMessageCache.get(sessionId);
            if (messageRecords == null) {
                  messageRecords = new LinkedList<>();
            }
            messageRecords.add(messageRecord);
            sessionMessageCache.put(sessionId, messageRecords);
      }

      // 从缓存中检索消息记录
      public Deque<ChatDTO.MessageRecord> getMessageRecordsFromCache(Long sessionId) {
            return sessionMessageCache.get(sessionId);
      }

      public void  removeRecord(Long sessionId){
            sessionMessageCache.put(sessionId,new LinkedList<>());
      }

      // 根据 sessionId 清除缓存中的消息记录
      public void invalidateSession(Long sessionId) {
            sessionMessageCache.invalidate(sessionId);
      }

      public LinkedList<Message> getSessionMessagedForApi(Long sessionId){
            Deque<ChatDTO.MessageRecord> d = sessionMessageCache.get(sessionId);
            if (Objects.isNull(d)){
                  return  new LinkedList<>();
            }
            List<Message> r  = new ArrayList<>();
            for (ChatDTO.MessageRecord messageRecord : d) {
                  Message c = new Message();
                  if (!CollectionUtils.isEmpty(messageRecord.getMessages())){
                        for (Message message : messageRecord.getMessages()) {
                              Message target = new Message();
                              BeanUtils.copyProperties(message,target);
                              r.add(target);
                        }
                        continue;
                  }
                  BeanUtils.copyProperties(messageRecord,c);
                  r.add(c);
            }
            return new LinkedList<>(r);
      }




//      private Deque<ChatDTO.MessageRecord> loadSessionMessage(Long sessionId){
//            Deque<ChatDTO.MessageRecord> res =  new LinkedList<>();
//            if(null == chatSession || CollectionUtils.isEmpty(records)){
//                  return res;
//            }
//            List<ChatDTO.MessageRecord> s = records.stream().map((i)->{
//                  if(Objects.isNull(i)){}
//                  ChatDTO.MessageRecord record = new ChatDTO.MessageRecord();
//                  record =  ChatDTO.toMessage(i.getRecordType(),i.getContent(),i.getOriginMessages());
//                  record.setQuery_type(i.getQueryType());
//                  record.setRecordId(i.getRecordId());
//                  record.setSynthesized(i.getSynthesized());
//                  record.setAudioDuration(i.getAudioDuration());
//                  //TODO 其他业务传递值增加
//                  return record;
//            }).collect(Collectors.toList());
//            res.addAll(s);
//            return res;
//      }


      public SseEmitter getEmitter(String sseId){
            return emitterCache.get(sseId);
      }

//      public LinkedList<ChatDTO.MessageRecord> getSessionMessaged(Long sessionId){
//            return new LinkedList<>(sessionMessageCache.get(sessionId));
//      }
//
//      public void refreshSessionCache(Long sessionId){sessionMessageCache.refresh(sessionId);
//      }
//
//      public void addSessionMessage(Long sessionId,ChatDTO.MessageRecord message){
//            sessionMessageCache.get(sessionId).add(message);
//      }

      public void addTmpMessage(String recordId ,ChatDTO.MessageRecord record){
            tmpMessageCache.put(recordId,record);
      }

      public ChatDTO.MessageRecord getTmpMessage(String recordId){
           return  tmpMessageCache.get(recordId);
      }

      public void invalidateEmitter(String sseId){
            emitterCache.invalidate(sseId);
      }

}
